package jvm.jtacck.db.records;

import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;

/**
 * 
 * @author Chris Gamble
 * 
 *         Represents a Specimen of the tracking system. A specimen is comprised
 *         of a Collection of Items, as well as a unique barcode, a description
 *         of the specimen as well as requirements of shipping for the specimen.
 *         The collection of Items represents the contains table of the
 *         database, where one Specimen may contain multiple Items, but two
 *         Specimens cannot contain the same Item.
 */
public class Specimen extends Record {

    private static final long serialVersionUID = -5530188823133494025L;
    public final String barcode;
    public final String description;
    public final String requirements;
    public final Collection<Item> contents;

    /**
     * Constructs a Specimen
     * 
     * @param barcode
     *            unique integer for an instance
     *            NON-NULLABLE
     * @param description
     *            an English description of the Specimen.
     * @param requirements
     *            an English explanation of shipping requirements for the
     *            Specimen.
     * @param contents
     *            A collection of the Items contained by the Specimen. Must not
     *            be empty.
     *            NON-NULLABLE
     */
    public Specimen(String barcode, String description, String requirements,
            Collection<Item> contents) {
        this.barcode = barcode;
        this.description = description;
        this.requirements = requirements;
        this.contents = Collections.unmodifiableList(new LinkedList<Item>(contents));
        
    }
    
    @Override
    public boolean equals(Object o){
        if (o instanceof Specimen) {
            Specimen other = (Specimen) o;
            return (barcode.equals(other.barcode)) &&
                   checkString(description, other.description) &&
                   checkString(requirements, other.requirements) &&
                   contents.equals(other.contents);
        }
        return false;
    }
    
    public boolean checkString(String s1, String s2) {
        if (s1 == null) {
            return s2 == null;
        }else {
            return s1.equals(s2);
        }
    }
    
    @Override
    public int hashCode() {
        return barcode.hashCode() + description.hashCode() + 
        requirements.hashCode();
    }
    
    public String toString() {
        return barcode + ": " + description + ", " +  
                requirements + ", " + contents + ".";
    }

}
